﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using CastleDefender.ConfigFolder;
using CastleDefender.Platform.ScreenBehavior;

namespace CastleDefender.Platform
{
    public abstract class GameObject :DrawableGameComponent
    {
        #region VARIABLE

        protected SpriteBatch sprBatch;
        protected Vector2 vecPosition;
        protected Texture2D ttTexture;
        protected TouchBehavior mtTouch;
        protected List<List<Rectangle>> frames;
        protected int intHeightFrame;
        protected int intWidthFrame;
        protected float fltRotation;
        protected float fltScale;
        protected Vector2 vecOrigin;
        protected Rectangle recBounds;
        protected int intState;
        protected int intOldState;
        protected int intActiveFrame;
        protected Rectangle recCurrentFrame;
        
        #endregion

        #region CONSTRUCTOR


        public GameObject(Game myGame,ref Texture2D texture, int widthframe, int heightframe)
            : base(myGame)
        {
            sprBatch = (SpriteBatch)myGame.Services.GetService(typeof(SpriteBatch));
            fltRotation = 0;
            fltScale = 1;
            vecOrigin = Vector2.Zero;
            ttTexture = texture;
            intWidthFrame = widthframe;
            intHeightFrame = heightframe;
            intState = intActiveFrame = 0;
            frames = new List<List<Rectangle>>();

            int xframe = ttTexture.Width / intWidthFrame;
            int yframe = ttTexture.Height / intHeightFrame;
            int X = 0, Y = 0;

            frames = new List<List<Rectangle>>();

            //lấy frame hình theo hàng
            for (int i = 0; i < yframe; i++)
            {
                //lấy frame hình theo cột
                X = 0;
                List<Rectangle> columnList = new List<Rectangle>();
                for (int j = 0; j < xframe; j++)
                {
                    //Thêm vào list cột một frame hình mới
                    columnList.Add(new Rectangle(X, Y, intWidthFrame, intHeightFrame));

                    //Tăng tọa độ X trong texture
                    X += intWidthFrame;
                }

                frames.Add(columnList);

                //Tăng tọa độ Y trong texture
                Y += intHeightFrame;
            }
        }
        #endregion

        #region PUBLIC METHOD

        public override void Draw(GameTime gameTime)
        {
            recCurrentFrame = frames[intState][intActiveFrame];
            if (Visible)
            {
                sprBatch.Draw(ttTexture, vecPosition, recCurrentFrame, Color.White, fltRotation, vecOrigin, fltScale, SpriteEffects.None, 0);
            }
            base.Draw(gameTime);
        }

        #endregion

        #region PROTECTED METHOD

        //Tính góc quay Rotation của đối tượng dựa vào vector trọng trường và vector chỉ hướng
        protected float AngleRotation(Vector2 vectorDirection)
        {
            float rotation = fltRotation;
            if (vectorDirection != Vector2.Zero)
            {
                //Tính góc A hợp bởi vector chỉ phương và vector trọng trường
                float cosA = (vectorDirection * Config.VectorG).Length() / (vectorDirection.Length() * Config.VectorG.Length());
                float A = (float)Math.Acos(cosA);


                //Vector chỉ phương nằm trong phần góc thứ I
                if (vectorDirection.X > 0 && vectorDirection.Y >= 0)
                {
                    //vector rotaion nằm ở phần góc thứ IV hệ trục tọa độ mới
                    rotation = -A + Config.PI;
                }

                //Vector chỉ phương nằm trong phần góc thứ II
                if (vectorDirection.X <= 0 && vectorDirection.Y > 0)
                {
                    //vector rotaion nằm ở phần góc thứ III hệ trục tọa độ mới
                    rotation = A - Config.PI;
                }

                //Vector chỉ phương nằm trong phần góc thứ III
                if (vectorDirection.X < 0 && vectorDirection.Y <= 0)
                {
                    //vector rotaion nằm ở phần góc thứ II hệ trục tọa độ mới
                    rotation = -A;
                }

                //Vector chỉ phương nằm trong phần góc thứ IV
                if (vectorDirection.X >= 0 && vectorDirection.Y < 0)
                {
                    //vector rotaion nằm ở phần góc thứ I hệ trục tọa độ mới
                    rotation = A;
                }
            }
            return rotation;
        }
        #endregion

        #region PUBLIC PROPERTIES

        //Nhận trả giá trị biến vecPosition
        public Vector2 Position
        {
            get { return vecPosition; }
            set { vecPosition = value; }
        }

        //Nhận trả giá trị biến intState
        public int State
        {
            get { return intState; }
            set { intState = value; }
        }

        //Nhận trả giá trị biến intActiveFrame
        public int ActiveFrame
        {
            get { return intActiveFrame; }
            set { intActiveFrame = value; }
        }

        //Nhận trả giá trị biến recBounds
        public Rectangle Bounds
        {
            get { return recBounds; }
            set { recBounds = value; }
        }

        //Nhận trả giá trị góc xoay
        public float Rotation
        {
            get { return fltRotation; }
            set { fltRotation = value; }
        }

        //Trả giá trị intWidthFrame
        public int WidthFrame
        {
            get { return intWidthFrame; }
        }

        //Trả giá trị intHeightFrame
        public int HeightFrame
        {
            get { return intHeightFrame; }
        }

        //Trả giá trị frame
        public List<List<Rectangle>> Frames
        {
            get { return frames; }
        }
        #endregion

     
    }
}
